package com.example.demo.controller;

import com.example.demo.model.Torrent;
import com.example.demo.service.TorrentService;
import com.example.demo.utils.BencodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpServletRequest; // 注意这里 import jakarta
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.HexFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.example.demo.utils.TorrentUtil.bytesToHex;

@RestController
public class TrackerController {
    @Autowired
    private final TorrentService torrentService;

    @Autowired
    public TrackerController(TorrentService torrentService) {
        this.torrentService = torrentService;
    }

    private String getInfoHash(String queryStr) throws UnsupportedEncodingException {
        Pattern INFO_HASH = Pattern.compile("info_hash=([^&]+)");
        Matcher matcher = INFO_HASH.matcher(queryStr);
        StringBuilder hexString = new StringBuilder();
        if (matcher.find()) {
            String matchedHash = matcher.group(1);
            String decodeInfoHash = URLDecoder.decode(matchedHash, "ISO-8859-1");
            byte[] infoHashBytes = decodeInfoHash.getBytes("ISO-8859-1");
            for (byte b : infoHashBytes) {
                String hex = Integer.toHexString(b & 0xFF);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } else {
            return null;
        }
    }
    @GetMapping("/announce")
    public ResponseEntity<String> announce(
            @RequestParam String info_hash,
            @RequestParam String peer_id,
            @RequestParam int port,
            @RequestParam long uploaded,
            @RequestParam long downloaded,
            @RequestParam long left,
            @RequestParam(defaultValue = "") String event,
            @RequestParam(name = "compact", defaultValue = "1") int compact,
            @RequestParam("passkey") String passkey,//用户唯一passkey(以user_id为key)
            HttpServletRequest request)throws Exception {
        // TODO : passkey

        // 获取客户端真实IP
        String clientIp = getClientIp(request);

        String queryString = request.getQueryString();
        String infoHash = getInfoHash(queryString);
        System.out.println("test: " + clientIp);

        Torrent torrent = torrentService.getTorrentByHash(infoHash);
        if (torrent == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Torrent not found");
        }

        // 3. 记录使用量
        // 2. 统计使用行为
        if (left == 0) {
            // 做种行为（已完成下载）
            torrentService.incrementUploadCount(torrent.getId());
        } else {
            // 下载行为
            torrentService.incrementDownloadCount(torrent.getId());
        }
        System.out.println("uploaded: " + uploaded);
        System.out.println("downloaded: " + downloaded);



        // 注册Peer信息
        torrentService.registerPeer(infoHash, peer_id, port, clientIp,left,uploaded,downloaded,passkey);
        // 构建响应数据
        Map<String, Object> response = new LinkedHashMap<>();
        response.put("interval", 1800);
        response.put("complete", torrentService.getTorrentByHash(infoHash).getSeeders());
        response.put("incomplete", torrentService.getTorrentByHash(infoHash).getLeechers());
        response.put("peers", torrentService.getCompactPeerList(infoHash));
        System.out.println("response: " + response);
        String bencodedResponse;
        bencodedResponse = BencodeUtil.encodeISO(response);
        System.out.println("bencodedResponse: " + bencodedResponse);
        return ResponseEntity.ok()
                .header("Content-Type", "text/plain; charset=ISO_8859_1")
                .header("Connection", "close")
               .body(bencodedResponse);


    }

    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.split(",")[0];
    }
}